﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using UI_Editor.Properties;
using System.Drawing.Drawing2D;

namespace UI_Editor.Widgets
{
    public partial class RenderScene : UserControl
    {
        private float renderSize = 1f;
        public List<SpriteNode> childs = new List<SpriteNode>();

        [Bindable(true), Category("渲染"), Description("显示尺寸")]
        public float RenderSize
        {
            get { return renderSize; }
            set { renderSize = value; if (renderSize < 0) renderSize = 0; }
        }

        public Rectangle Rect;
        [Bindable(true), Category("渲染"), Description("渲染区域")]
        public Rectangle RenderRectangle
        {
            get { return Rect; }
            set { Rect = value; }
        }

        private string _name = "scene1";
        [Bindable(true), Category("渲染"), DefaultValue(null), Description("控件名称")]
        public string name
        {
            get { return _name; }
            set { _name = value; }
        }

        private PointF selectStartPos = PointF.Empty;
        private PointF selectCurPos = PointF.Empty;

        public RenderScene()
        {
            InitializeComponent();

            this.Paint += new PaintEventHandler(this.PaintScene);

            this.MouseDown += new MouseEventHandler(this.SceneMouseDown);
            this.MouseMove += new MouseEventHandler(this.SceneMouseMove);
            this.MouseUp += new MouseEventHandler(this.SceneMouseUp);

            this.MouseWheel += new MouseEventHandler(this.SceneMouseWheel);
            this.KeyDown += new KeyEventHandler(this.SceneKeyDown);
        }

        /// <summary>
        /// 进行当前控件的绘制，绘制场景和场景中的子控件
        /// </summary>
        public void PaintScene(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.ResetClip();

            GraphicsState State1 = g.Save();
            g.ScaleTransform(renderSize, renderSize);   //尺寸缩放

            GraphicsState transState = g.Save();
            g.TranslateTransform(Rect.X, Rect.Y);       //坐标偏移
            //
            //使用纹理刷进行背景的填充绘制，网格透明背景
            //
            TextureBrush brush = new TextureBrush(Resources.TransBg, System.Drawing.Drawing2D.WrapMode.Tile);
            if (Rect.IsEmpty) Rect = new Rectangle(0, 0, this.Size.Width, this.Size.Height);
            g.FillRectangle(brush, 0, 0, Rect.Width, Rect.Height);
            //
            //绘制场景中的子控件
            //
            foreach (SpriteNode child in childs)
            {
                child.Paint_this(e);
            }
            g.Restore(transState);

            g.Restore(State1);
        }

        //记录各类型控件的总数目
        private Dictionary<string, int>  childsCount = new Dictionary<string, int>();
        /// <summary>
        /// 累计各类型控件数目
        /// </summary>
        private void childsCountAdd(string type)
        {
            if (childsCount.Keys.Contains(type)) childsCount[type]++;
            else childsCount.Add(type, 1);
        }

        /// <summary>
        /// 点击渲染界面响应逻辑
        /// </summary>
        protected void SceneMouseDown(object sender, MouseEventArgs e)
        {
            //bool isClickControl = (Control.ModifierKeys & Keys.Control) == Keys.Control;
            //bool isClickAlt = (Control.ModifierKeys & Keys.Alt) == Keys.Alt;

            if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right) selectStartPos = selectCurPos = new PointF(e.X, e.Y);
            if (e.Button == MouseButtons.Left)
            {
                PointF P;
                if (cursorState == CursorState.Default || cursorState == CursorState.All)
                {
                    selectedChild = getSelectSprite(e);    //鼠标光标为默认状态时，选中新的子控件
                }

                if (MainForm.listView.SelectedItems.Count > 0)
                {
                    string type = MainForm.listView.SelectedItems[0].Text;
                    
                    if (type.Equals("Sprite") || type.Equals("Button"))
                    {
                        childsCountAdd(type);

                        //
                        //以鼠标点击处为中心，创建SpriteNode
                        //
                        SpriteNode sprite = null;
                        if(type.Equals("Sprite")) sprite = new SpriteNode();
                        else if (type.Equals("Button")) sprite = new SpriteButton();

                        sprite.name = type + childsCount[type]; //生成控件名
                        sprite.BackImage = MainForm.Img;        //设置控件默认图像

                        if (selectedChild != null)
                        {
                            P = selectedChild.RelativePoint;
                            sprite.Location = new Point((int)(P.X - sprite.Width / 2), (int)(P.Y - sprite.Height / 2));
                            selectedChild.addChild(sprite);
                        }
                        else
                        {
                            P = this.toRelative(e.X, e.Y);
                            sprite.Location = new Point((int)(P.X - sprite.Width / 2), (int)(P.Y - sprite.Height / 2));
                            this.childs.Add(sprite);
                        }

                        selectedChild = sprite;                     //设为选中的控件
                        MainForm.listView.SelectedItems.Clear();    //清除在工具栏中的选择

                        this.Cursor = Cursors.Default;
                    }
                }

                if (selectedChild != null) selectedChild.isSelect = true;
            }
        }

        SpriteNode selectedChild;
        /// <summary>
        /// 获取鼠标点击处的子控件
        /// </summary>
        private SpriteNode getSelectSprite(MouseEventArgs e)
        {
            unSelect();
            
            SpriteNode tmp = null;
            PointF P = toRelative(e.X, e.Y);    //获取相对坐标

            for (int i = childs.Count-1; i >= 0; i--)
            {
                tmp = childs[i].getSelectSprite(P);
                if (tmp != null)
                {
                    setCursor(CursorState.All); //选中控件后，设置鼠标光标为SizeAll
                    break;
                }
            }
            //foreach (SpriteNode child in childs)
            //{
            //    tmp = child.getSelectSprite(P);
            //    if (tmp != null)
            //    {
            //        setCursor(CursorState.All); //选中控件后，设置鼠标光标为SizeAll
            //        break;
            //    }
            //}
            return tmp;
        }

        /// <summary>
        /// 取消所有子控件的选中
        /// </summary>
        public void unSelect()
        {
            foreach (SpriteNode child in childs) child.unSelect();
        }


        /// <summary>
        /// 实际像素坐标(X, Y) 转化为相对于网格背景的坐标
        /// </summary>
        private PointF toRelative(float X, float Y)
        {
            return new PointF((X - Rect.X * renderSize) / renderSize, (Y - Rect.Y * renderSize) / renderSize);
        }

        /// <summary>
        /// 网格背景的坐标(X, Y) 转化为场景坐标
        /// </summary>
        private PointF toSceen(float X, float Y)
        {
            return new PointF((X + Rect.X) * renderSize, (Y + Rect.Y) * renderSize);
        }

        private SizeF tmpSize = new SizeF(0, 0);
        protected void SceneMouseMove(object sender, MouseEventArgs e)
        {
            //鼠标拖动
            if(e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
            {
                selectCurPos = new PointF(e.X, e.Y);
                SizeF moveSize = new SizeF((selectCurPos.X - selectStartPos.X) / renderSize, (selectCurPos.Y - selectStartPos.Y) / renderSize); //渲染尺寸转换为实际尺寸
                moveSize += tmpSize;

                if (Math.Abs(moveSize.Width) < 1 && Math.Abs(moveSize.Height) < 1) return;                          //每次至少移动一个像素
                tmpSize = new SizeF(moveSize.Width - (int)moveSize.Width, moveSize.Height - (int)moveSize.Height);  //记录上次舍去值

                System.Threading.Thread.Sleep(15);
                selectStartPos = selectCurPos;

                //右键按下拖动整个渲染界面
                if (e.Button == MouseButtons.Right)
                {
                    Rect.Location += new Size((int)moveSize.Width, (int)moveSize.Height);
                }
                //左键按下
                else
                {
                    //选中的子控件
                    if (selectedChild != null && selectedChild.isSelect)
                    {
                        //移动
                        if (cursorState == CursorState.All)
                        {
                            selectedChild.Left += (int)moveSize.Width;
                            selectedChild.Top += (int)moveSize.Height;
                        }
                        //调整大小
                        else
                        {
                            if (cursorState == CursorState.S || cursorState == CursorState.SW || cursorState == CursorState.SE)
                                selectedChild.Height += (int)moveSize.Height;
                            else if (cursorState == CursorState.N || cursorState == CursorState.NW || cursorState == CursorState.NE)
                            {
                                selectedChild.Top += (int)moveSize.Height;
                                selectedChild.Height -= (int)moveSize.Height;
                            }

                            if (cursorState == CursorState.E || cursorState == CursorState.NE || cursorState == CursorState.SE)
                                selectedChild.Width += (int)moveSize.Width;
                            else if (cursorState == CursorState.W || cursorState == CursorState.NW || cursorState == CursorState.SW)
                            {
                                selectedChild.Left += (int)moveSize.Width;
                                selectedChild.Width -= (int)moveSize.Width;
                            }
                        }

                        //限定控件在父控件范围内
                        Rectangle Rect;
                        if (selectedChild.parent != null) Rect = selectedChild.parent.getRect();
                        //else Rect = 
                    }
                }

                this.Refresh();
            }
            //鼠标移动
            else
            {
                //添加控件光标
                if (MainForm.listView.SelectedItems.Count > 0)
                    this.Cursor = MainForm.cursor;
                //子控件上显示光标
                else  if (selectedChild != null && selectedChild.isSelect)
                {
                    PointF point = toRelative(e.X, e.Y);    //获取相对坐标
                    CursorState state = getCursorState(selectedChild.getScreenRectF(), point); //获取光标状态
                    setCursor(state);                       //设置光标 
                }
            }
        }

        #region  子控件光标属性

        private CursorState cursorState = CursorState.Default;
        private enum CursorState { NW, SE, NE, SW, N, S, W, E, All, Default }; //鼠标光标状态

        /// <summary>
        /// 根据鼠标在控件上的位置,设置光标
        /// </summary>
        private CursorState getCursorState(RectangleF Rect, PointF point)
        {
            RectangleF[] tmp = new RectangleF[9];
            float s = 3 / renderSize, s2 = 2 * s;

            tmp[0] = new RectangleF(Rect.X - s, Rect.Y - s, s2, s2);
            tmp[1] = new RectangleF(Rect.Right - s, Rect.Bottom - s, s2, s2);

            tmp[2] = new RectangleF(Rect.Right - s, Rect.Y - s, s2, s2);
            tmp[3] = new RectangleF(Rect.X - s, Rect.Bottom - s, s2, s2);

            tmp[4] = new RectangleF(Rect.X + s, Rect.Y - s, Rect.Width - s2, s2);
            tmp[5] = new RectangleF(Rect.X + s, Rect.Bottom - s, Rect.Width - s2, s2);

            tmp[6] = new RectangleF(Rect.X - s, Rect.Y + s, s2, Rect.Height - s2);
            tmp[7] = new RectangleF(Rect.Right - s, Rect.Y + s, s2, Rect.Height - s2);

            tmp[8] = new RectangleF(Rect.X + s, Rect.Y + s, Rect.Width - s2, Rect.Height - s2);

            for (int i = 0; i < tmp.Length; i++)
            {
                if (tmp[i].Contains(point)) return (CursorState)i; 
            }
            return CursorState.Default;
        }

        /// <summary>
        /// 根据光标状态设置显示光标,记录当前光标状态
        /// </summary>
        private void setCursor(CursorState cursorState)
        {
            if (cursorState == CursorState.NW || cursorState == CursorState.SE) this.Cursor = Cursors.SizeNWSE;
            else if (cursorState == CursorState.NE || cursorState == CursorState.SW) this.Cursor = Cursors.SizeNESW;
            else if (cursorState == CursorState.N || cursorState == CursorState.S) this.Cursor = Cursors.SizeNS;
            else if (cursorState == CursorState.W || cursorState == CursorState.E) this.Cursor = Cursors.SizeWE;
            else if (cursorState == CursorState.All) this.Cursor = Cursors.SizeAll;
            else this.Cursor = Cursors.Default;

            this.cursorState = cursorState;
        }

        #endregion


        protected void SceneMouseUp(object sender, MouseEventArgs e)
        {
            //mouseLeft = false;
            Refresh();

            //在PropForm中显示选中控件的属性
            if (selectedChild == null)
            {
                UI_Editor.DckForm.PropForm.SetObj(this, this.name);
                //UI_Editor.DckForm.PropForm.PropertyGrid.SelectedObject = this;
            }
            else //UI_Editor.DckForm.PropForm.PropertyGrid.SelectedObject = selectedChild;
                UI_Editor.DckForm.PropForm.SetObj(selectedChild, selectedChild.name);

            //MessageBox.Show("相对背景坐标：" + getRelative(e.X, e.Y).ToString());
        }

        /// <summary>
        /// 滚轮时，改变渲染尺寸、使渲染区居中显示
        /// </summary>
        protected void SceneMouseWheel(object sender, MouseEventArgs e)
        {
            renderSize *= 1 + e.Delta / 480f;

            //Rect.X = (int)((this.Width - Rect.Width * renderSize) / 2);
            //Rect.Y = (int)((this.Height - Rect.Height * renderSize) / 2);

            this.Invalidate();
        }

        /// <summary>
        /// 按键响应逻辑
        /// </summary>
        private void SceneKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if(selectedChild == null || !selectedChild.isSelect) return;

            //删除子控件
            if (e.KeyCode == Keys.Delete)
            {
                if (selectedChild.parent != null) selectedChild.remove();
                else childs.Remove(selectedChild);   //删除当前选中的控件
                selectedChild = null;

                setCursor(CursorState.Default); //设置为默认光标

                this.Invalidate();
            }
            else if (e.KeyCode == Keys.NumPad4) selectedChild.Left--;
            else if (e.KeyCode == Keys.NumPad6) selectedChild.Left++;
            else if (e.KeyCode == Keys.NumPad8) selectedChild.Top--;
            else if (e.KeyCode == Keys.NumPad2) selectedChild.Top++;

            this.Invalidate();
        }
    }
}
